﻿using System;
using System.Linq.Expressions;

namespace NMA.Infrastructure.NHibernate.OrderByExpression.Category
{
    using NMA.Domain.Shared;
    using NMA.Domain.Model;
    using NMA.Domain.Model.Contract;
    /// <summary>
    /// http://www.singingeels.com/Articles/Self_Sorting_GridView_with_LINQ_Expression_Trees.aspx
    /// </summary>
    public class SearchCategoryOrderByExpression : OrderByExpressionBase<ICategory, SearchCategoryOrderByType>
    {
        public override Func<ICategory, object> CreatedCriteriaExpression(SearchCategoryOrderByType orderByType)
        {
            Expression<Func<ICategory, object>> result = null;

            switch (orderByType)
            {
                case SearchCategoryOrderByType.Id:
                    result = GetIdOrderExpression();
                    break;
                case SearchCategoryOrderByType.Name:
                    result = GetNameOrderExpression();
                    break;
                case SearchCategoryOrderByType.CreatedUser:
                    result = GetCreatedUserOrderExpression();
                    break;
                case SearchCategoryOrderByType.CreatedDate:
                    result = GetCreatedDateOrderExpression();
                    break;
                default:
                    break;
            }

            return result.Compile();
        }

        private Expression<Func<ICategory, object>> GetIdOrderExpression()
        {
            var param = Expression.Parameter(typeof(IEntity<ICategory>), "c");

            var sortExpression = Expression.Lambda<Func<ICategory, object>>(Expression.Convert(Expression.Property(param, "Id"), typeof(object)), param);

            return sortExpression;
        }

        private Expression<Func<ICategory, object>> GetNameOrderExpression()
        {
            var param = Expression.Parameter(typeof(INameEntity<ICategory>), "c");

            var sortExpression = Expression.Lambda<Func<ICategory, object>>(Expression.Convert(Expression.Property(param, "Name"), typeof(object)), param);

            return sortExpression;
        }

        private Expression<Func<ICategory, object>> GetCreatedUserOrderExpression()
        {
            var param = Expression.Parameter(typeof(ICategory), "c");

            var sortExpression = Expression.Lambda<Func<ICategory, object>>(Expression.Convert(Expression.Property(param, "CreatedUser"), typeof(object)), param);

            return sortExpression;
        }

        private Expression<Func<ICategory, object>> GetCreatedDateOrderExpression()
        {
            var param = Expression.Parameter(typeof(IEntity<ICategory>), "c");

            var sortExpression = Expression.Lambda<Func<ICategory, object>>(Expression.Convert(Expression.Property(param, "CreatedDate"), typeof(object)), param);

            return sortExpression;
        }
    }
}